#!/usr/bin/python3
# -*-coding:utf-8 -*

"""  Fichier regroupant les fonctions, classes de gestion des éléments animés de l'écran """

# IMPORTS
from pygame import Rect
from pygame.display import get_surface
from pygame.sprite import Sprite
from operator import add,mul,sub
from config import MOVEMENT,UP,DOWN,LEFT,RIGHT,STEP_ACCEPT
from config import TILE_WIDTH,TILE_HEIGHT
from frames import AnimatedSpriteFrame

class BaseSprite(Sprite):

    """
        Classe de mère de gestrion des sprites
        
        Paramètres:
        tuple position - position du sprite sur une map
        surface image - l'image du sprite
        rect rect - contour de l'image du sprite
        rect oldRect - ancien contour de l'image du sprite
        
    """

    def __init__(self,fileSpriteName,initPosition):
        """
            Constructeur de la classe
            
            Paramètres nommés:
            str fileSpriteName - nom du fichier du sprite
            tuple initPosition - coordonnées du sprite sur une map
            
        """
        # Constructeur de la classe mère
        Sprite.__init__(self)
        # Objet de gestion des frames du sprite
        self.frame=AnimatedSpriteFrame(fileSpriteName)
        # Gestion de l'image du sprite
        self.image=self.frame.currentImage
        # Gestion du contour du sprite
        self.rect=self.image.get_rect()
        # Gestion de la position initiale du sprite
        self.__setInitPosition(initPosition)

    def __setInitPosition(self,initPosition):
        """
            Méthode de mise en place du sprite initial
            
            Paramètres nommés:
            tuple initPosition - coordonnées du sprite sur une map
            
        """
        # Convertion
        self.position=self.__convertMapPositionToReal(initPosition)
        # Mise à jour du positionnement dans limage
        self.rect.midleft=self.position

    def __convertMapPositionToReal(self,mapPosition):
        """
            Fonction de convertion des coordonnées de carte en une position réelle
            
            Paramètre nommée;
            tuple position - coordonnées du sprite sur une map
            
            Retour:
            tuple
            
        """
        return tuple(map(mul,mapPosition,(TILE_WIDTH,TILE_HEIGHT)))

    def setPosition(self,position):
        """
            Méthode de gestion de la position du sprite
            
            Paramètre nommé:
            tuple tilePosition - coordonnées du sprite
            
        """
        # Variable delta entre les deux positions
        delta=tuple(map(sub,position,self.position))
        # Gestion du type pour maj variable position
        self.position=position
        # Déplacement du sprite
        self.__moveToPosition(delta)

    def __moveToPosition(self,delta):
        """
            Méthode de déplacement du sprite à lécran
            
            Paramètre nommé:
            tuple delta - delta de déplacement du sprite
            
        """
        # Sauvegarde de l'ancienne position du sprite pour pouvoir l'effacer
        self.oldRect=self.rect
        # Nouvelle position
        self.rect.move_ip(delta[0],delta[1])

    def update(self,direction):
        """ 
            Méthode de mise à jour du sprite
            
            Paramètre nommé:
            int - clé de la direction du joueur (UP, DOWN, STAY ....)
        """
        pass

class Player(BaseSprite):

    """
        Classe de gestrion du joueur
        
        Paramètres:
        tuple position - position du sprite sur une map
        Surface image - l'image du sprite
        Rect rect - contour de l'image du sprite
        Map currentMap - carte sur laquelle se trouve le joueur
        Rect vision - champ de vision du joueur
        
    """

    def __init__(self,fileSpriteName,initPosition,currentMap):
        """
            Constructeur de la classe
            
            Paramètres nommés:
            str fileSpriteName - nom du fichier du sprite
            tuple initPosition - coordonnées du sprite sur une map
            Map currentMap - map sur laquel se trouve la joueur
            
        """
        # Appel du constructeur de la classe mère
        BaseSprite.__init__(self,fileSpriteName,initPosition)
        # Mise en place de la map sur laquelle se trouve le joueur
        self.currentMap=currentMap
        # Mise en place du champ de vision initiale du joueur
        self.vision=Rect((0,0),get_surface().get_size()) # TODO Gestion de la vision initiale du joueur


    def update(self,direction):
        """ 
            Méthode de mise à jour du joueur sur l'écran
            
            Paramètre nommé:
            int - clé de la direction du joueur (UP, DOWN, STAY ....)
            
        """
        # Nouvelle position
        newPos=None
        # Test déplacement du joueur
        # 1°) Direction donnée
        if self.currentMap.canCross(self.rect,direction):
            # Nouvelle position
            newPos=tuple(map(add,self.position,MOVEMENT[direction]))

        # TODO Gestion de la correction de mouvement

        if newPos:
            # Déplacement du sprite
            self.setPosition(newPos)
            # Vision du joueur
            self.__updateVision(direction)

        # Nouvelle image
        self.image=self.frame.nextFrame(direction)

    def __updateVision(self,direction):
        """
            Méthode de mise à jour de la vision de l'utilisateur
            
            Paramètre nommé:
            int - clé de la direction du joueur (UP, DOWN, STAY ....)
        
        """
        pass
